package cn.zcy.typefilter;


import cn.zcy.annotations.District;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.type.filter.AbstractTypeHierarchyTraversingFilter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.ClassUtils;
import org.springframework.util.PathMatcher;

import java.util.Properties;

/**
 * 自定义扫描规则过滤器
 */
public class DistrictTypeFilter extends AbstractTypeHierarchyTraversingFilter {
    //定义路径校验对象
    private PathMatcher pathMatcher;
    //定义区域名称

    private String districtName;

    /**
     * 调用父类的构造
     * 第一个参数 不考虑基类
     * 第二个参数 不考虑借口上的信息
     */
    public DistrictTypeFilter() {
        super(false, false);
        //借助spring默认的Resources通配符路径
        pathMatcher = new AntPathMatcher();

        try {
            //读取配置文件
            Properties properties = PropertiesLoaderUtils.loadAllProperties("district.properties");
            districtName = properties.getProperty("common.district.name");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 本类将注册为exclude，返回true表示拒绝
     *
     * @param className
     * @return
     */
    @Override
    protected boolean matchClassName(String className) {
        try {
                /**
                 * 判断是否在指定包下的类
                 */
                if (!isPotentialPackageClass(className)) {
                    //不符合路径规则
                    return false;
            }
            //判断当前区域和配置区域是否一致，不一致则不能注册到spring的ioc容器中
            Class<?> clazz = ClassUtils.forName(className, DistrictTypeFilter.class.getClassLoader());
            //获取District注解
            District district = clazz.getAnnotation(District.class);
            //判断是否有此注解

            if (district == null) {
                return false;
            }
            //取出注解的属性
            String districtValue = district.value();
            //校验  north / north
            return (!districtName.equalsIgnoreCase(districtValue));
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    //定义可以处理的类名，指定package下
    private static final String PATTER_STANDARD = ClassUtils.convertClassNameToResourcePath("cn.zcy.service.*.*");

    /**
     * 本来逻辑中可以处理的类
     *
     * @param calssName
     * @return
     */
    private boolean isPotentialPackageClass(String calssName) {
//将类名转化成资源路径
        String path = ClassUtils.convertClassNameToResourcePath(calssName);
        //校验
        boolean match = pathMatcher.match(PATTER_STANDARD, path);
        return match;
    }
}
